package com.taiji.dianthus.service.sms.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.taiji.dianthus.common.BusinessMessage;
import com.taiji.dianthus.common.ResultCodeEnum;
import com.taiji.dianthus.dao.sms.SmsInfoRepository;
import com.taiji.dianthus.domain.sms.SmsAccount;
import com.taiji.dianthus.domain.sms.SmsInfo;
import com.taiji.dianthus.service.sms.SmsAccountService;
import com.taiji.dianthus.service.sms.SmsInfoService;
import com.taiji.dianthus.sms.HttpSendSmsService;
import com.taiji.dianthus.util.DStringUtil;
import com.taiji.dianthus.util.DateUtil;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @ClassName SmsInfoServiceImnpl
 * @Description
 * @Author H.M
 * @Date 2020/7/15
 */
@Service
public class SmsInfoServiceImpl implements SmsInfoService {

    @Autowired
    private SmsInfoRepository repository;
    @Autowired
    private HttpSendSmsService httpSendSmsService;

    @Autowired
    private SmsAccountService accountService;

    /**
     * 保存方法
     *
     * @param smsInfo
     */
    @Override
    public BusinessMessage save(SmsInfo smsInfo) {
        BusinessMessage message = new BusinessMessage();
        try {
            smsInfo.setCreateTime(new Date());
            if (StringUtils.isEmpty(smsInfo.getMsgTime())) {
                smsInfo.setMsgTime(new Date());
            }
            repository.saveAndFlush(smsInfo);
            message.setMsg("保存成功");
            message.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            message.setMsg("保存失败");
        }
        return message;
    }

    @Override
    public BusinessMessage draftsList(Integer currentPage, Integer pageSize, Date start, Date end, String id, Integer msgLoc) {
        BusinessMessage message = new BusinessMessage();
        try {
            Sort sort = new Sort(Sort.Direction.DESC, "createTime");
            //分页参数
            Pageable pageable = PageRequest.of(currentPage, pageSize, sort);
            Page<SmsInfo> draftsPage;
            //创建查询参数
            Specification<SmsInfo> spec = (Root<SmsInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
                List<Predicate> pl = new ArrayList<Predicate>();
                //开始时间
                if (start != null) {
                    pl.add(cb.greaterThanOrEqualTo(root.<Date>get("createTime"), start));
                }
                //结束时间
                if (end != null) {
                    pl.add(cb.lessThan(root.<Date>get("createTime"), end));
                }
                //查询未删除的
                pl.add(cb.equal(root.<Integer>get("enableFlag"), 1));
                pl.add(cb.equal(root.<String>get("sendUserId"), id));
                pl.add(cb.equal(root.<Integer>get("msgLoc"), msgLoc));
                return cb.and(pl.toArray(new Predicate[0]));
            };
            draftsPage = repository.findAll(spec, pageable);
            message.setMsg("查询列表成功");
            message.setData(draftsPage);
            message.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            message.setMsg("查询列表失败");
        } finally {
            return message;
        }
    }

    @Override
    public BusinessMessage deleteDrafts(String id) {
        BusinessMessage message = new BusinessMessage();
        try {
            repository.updateFlag(id);
            message.setSuccess(true);
            message.setMsg("删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            message.setMsg("删除失败,系统异常");
        }
        return message;
    }

    @Override
    public SmsInfo getOne(String id) {
        return repository.getOneById(id);

    }


    @Override
    public BusinessMessage updateMsgLoc(String id, Integer status) {
        BusinessMessage message = new BusinessMessage();
        try {
            repository.updateMsgLoc(id, status);
            message.setSuccess(true);
            message.setMsg("删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            message.setMsg("删除失败,系统异常");
        }
        return message;
    }

    @Override
    public List<SmsInfo> getTaskMsgByTime(Date time) {
        return repository.getTaskMsgByTime(time);
    }

    @Override
    public BusinessMessage editTaskTime(String id, String msgTime) {
        BusinessMessage message = new BusinessMessage();
        try {
            Date time = DateUtil.stringToDate(msgTime, "yyyy-MM-dd HH:mm");
            repository.editTaskTime(id, time);
            message.setSuccess(true);
            message.setMsg("保存成功");
        } catch (Exception e) {
            e.printStackTrace();
            message.setMsg("保存失败,系统异常");
        }
        return message;
    }

    @Override
    public BusinessMessage sendDSMS(SmsInfo smsInfo) {
        BusinessMessage message = new BusinessMessage();
        smsInfo.setCreateTime(new Date());
        smsInfo.setRetryCount(0);
        JSONArray objArr = new JSONArray();
        try {
            SmsAccount smsAccount = accountService.getInvalidBackAccount();
            if (smsAccount != null) {
                //发送短信 判断手机号是否超过100条 超过则按100划分成多个批次 每个批次只发送100个手机号 每批次发送完停留2秒 再送下一批次
                String receivePhone = smsInfo.getReceiveUserPhone();
                if (!StringUtils.isEmpty(receivePhone)) {
                    String[] phoneArr = DStringUtil.removeNullStringArray(receivePhone.split(","));
                    if (phoneArr.length > 100) {
                        int num = 100;
                        int count = phoneArr.length % num == 0 ? phoneArr.length / num : phoneArr.length / num + 1;
                        List<List<String>> arrayList = new ArrayList<>();
                        for (int i = 0; i < count; i++) {
                            int index = i * num;
                            List<String> list = new ArrayList<>();
                            int j = 0;
                            while (j < num && index < phoneArr.length) {
                                String phone = phoneArr[index++];
                                if (!StringUtils.isEmpty(phone)) {
                                    list.add(phone);
                                    j++;
                                }
                            }
                            arrayList.add(list);
                        }
                        for (List<String> list : arrayList) {
                            SmsInfo newSmsInfo = new SmsInfo();
                            BeanUtils.copyProperties(smsInfo, newSmsInfo);
                            newSmsInfo.setReceiveUserPhone(StringUtil.join(list.toArray(), ","));
                            objArr.add(httpSendSmsService.sendDSMS(newSmsInfo, smsAccount));
                            Thread.currentThread().sleep(2000);
                            System.out.println("====" + new Date());
                        }
                    } else {
                        objArr.add(httpSendSmsService.sendDSMS(smsInfo, smsAccount));
                    }
                    smsInfo.setSmsAccountId(smsAccount.getId());
                    //发送成功  更新账号使用时间use_time
                    accountService.updateUseTimeById(smsAccount.getId(), new Date());
                }
            } else {
                System.out.println("===没有可用发送短信的账号===" + smsInfo.toString());
                smsInfo.setMsgResultMsg("没有可用发送短信的账号");
                message.setMsg("没有可用账号");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (objArr != null && objArr.size() > 0) {
            List<String> msgGroupList = new ArrayList<>();
            for (int i = 0; i < objArr.size(); i++) {
                JSONObject obj = objArr.getJSONObject(i);
                if (obj.getBoolean("success")) {
                    msgGroupList.add(obj.getString("msgGroup"));
                }
            }
            JSONObject obj = objArr.getJSONObject(0);
            String report = obj.getString("rspcod");
            if (obj.getBoolean("success")) {
                message.setCode(1 + "");
                smsInfo.setMsgGroup(StringUtil.join(msgGroupList.toArray(), ","));
                smsInfo.setMsgResultMsg(report);
                smsInfo.setMsgResultCode(0 + "");
                smsInfo.setMsgStatus(0);
                message.setMsg("提交成功");
                message.setSuccess(true);
            } else if (!report.equals("") && report != null) {
                message.setCode(0 + "");
                if (report.equals(ResultCodeEnum.ILLEGAL_MAC.getCode())) {
                    message.setMsg(ResultCodeEnum.ILLEGAL_MAC.getMsg());
                } else if (report.equals(ResultCodeEnum.ILLEGAL_SIGNID.getCode())) {
                    message.setMsg(ResultCodeEnum.ILLEGAL_SIGNID.getMsg());
                } else if (report.equals(ResultCodeEnum.INVALID_MESSAGE.getCode())) {
                    message.setMsg(ResultCodeEnum.INVALID_MESSAGE.getMsg());
                } else if (report.equals(ResultCodeEnum.INVALID_USER_OR_PWD.getCode())) {
                    message.setMsg(ResultCodeEnum.INVALID_USER_OR_PWD.getMsg());
                } else if (report.equals(ResultCodeEnum.NO_SIGN_ID.getCode())) {
                    message.setMsg(ResultCodeEnum.NO_SIGN_ID.getMsg());
                } else if (report.equals(ResultCodeEnum.TOO_MANY_MOBILES.getCode())) {
                    message.setMsg(ResultCodeEnum.TOO_MANY_MOBILES.getMsg());
                } else if (report.equals(ResultCodeEnum.ConnectFalse.getCode())) {
                    message.setMsg(ResultCodeEnum.ConnectFalse.getMsg());
                }
                smsInfo.setMsgResultMsg(message.getMsg());
                smsInfo.setMsgResultCode(0 + "");
                smsInfo.setMsgStatus(2);
                smsInfo.setMsgStatusMsg("发送失败");
            }
            repository.saveAndFlush(smsInfo);
        }
        return message;
    }

    @Override
    public void updateStatusByGroup(String msgGroup, Integer status) {
        if (!StringUtils.isEmpty(msgGroup)) {
            msgGroup = "%" + msgGroup + "%";
        }
        repository.updateStatusByGroup(msgGroup, status);
    }

    @Override
    public SmsInfo getOneByMsgGroup(String msgGroup) {
        if (!StringUtils.isEmpty(msgGroup)) {
            msgGroup = "%" + msgGroup + "%";
        }
        return repository.getOneByMsgGroup(msgGroup);
    }

    @Override
    public List<SmsInfo> getAllByStatus(int i) {
        return repository.getAllByStatus(i);
    }

    @Override
    public void updateMsgStatusById(String id, int i) {
        repository.updateMsgStatus(id, i);
    }

    /**
     * 根据短信的号码查出发送信息id
     *
     * @param addSerial
     * @return
     */
    @Override
    public String getSmsInfoIdByMobile(String addSerial) {
        String smsId = null;
        try {
            Sort sort = new Sort(Sort.Direction.DESC, "createTime");
            //分页参数
            Pageable pageable = PageRequest.of(0, 1, sort);
            SmsAccount smsAccount = accountService.getIdByMobile(addSerial);
            try {
                List<SmsInfo> smsInfoList = repository.getIdByAccountId(pageable, smsAccount.getId());
                if (smsInfoList.size() > 0) {
                    smsId = smsInfoList.get(0).getId();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return smsId;
    }

    @Override
    public List<SmsInfo> getAllByTime(Date start, Date end, int retryCount) {
        return repository.getAllByTime(start, end, retryCount);
    }

    @Override
    public void updateRetryCount1(String id, int i, String smsGroup) {
        repository.updateRetryCount1(id, i, smsGroup);
    }

    @Override
    public void updateRetryCount2(String id, int i, String smsGroup) {
        repository.updateRetryCount2(id, i, smsGroup);
    }

}
